/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package org.yonsei.iwb.sdt.refinement.generator;

import com.hp.hpl.jena.rdf.model.Model;
import com.hp.hpl.jena.rdf.model.NodeIterator;
import com.hp.hpl.jena.rdf.model.Property;
import com.hp.hpl.jena.rdf.model.ResIterator;
import com.hp.hpl.jena.rdf.model.Resource;
import com.hp.hpl.jena.rdf.model.StmtIterator;
import java.util.ArrayList;
import java.util.List;
import java.util.Vector;
import org.yonsei.iwb.sdt.datastructure.DecomposeCandidate;
import org.yonsei.iwb.sdt.ontology.PropertyArc;
import org.yonsei.iwb.sdt.refinement.DLConstructors;
import org.yonsei.iwb.sdt.refinement.ExpandingHistory;
import org.yonsei.iwb.sdt.refinement.ExpandingHistorySet;
import org.yonsei.iwb.sdt.refinement.Refinement;
import org.yonsei.iwb.sdt.refinement.RefinementType;
import org.yonsei.iwb.sdt.util.UtilFunctions;

/**
 *
 * @author JDK
 */
public class QuantificationRefinementMaker implements Runnable{
    
    private Model model;
    private int ref_type;
    private Vector<Property> pset;
    
    public QuantificationRefinementMaker(Model model, int ref_type){
        this.model = model;
        this.ref_type = ref_type;
//        this.pset = propertyHistory;
    }
    
    @Override
    public void run() {
        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
    }    
    
    public ExpandingHistorySet expandingHistoryCounter(Vector<PropertyArc> propertyHistory, List<Resource> css){
        
        ExpandingHistorySet ehset = new ExpandingHistorySet();
        for (int j = propertyHistory.size()-1; j>-1  ; j--) {
            //여기서 ref를 여러개 생성함. 하나의ref에 대해서 refinementMaker 함수로 그의 negation form을 만들고 decomposecandidate를 생성.
            if(j==propertyHistory.size()-1){
                
                ExpandingHistory ex = this.getExistentialResources(new ExpandingHistory(), css, propertyHistory.get(j));
                ExpandingHistory uv = this.getUniversalResources(new ExpandingHistory(), css, propertyHistory.get(j));
                
                if(!ex.getInstanceSet().isEmpty()){
                    ehset.add(ex);
                }
                
                if(!uv.getInstanceSet().isEmpty()){
                    ehset.add(uv);                    
                }                                
            }else{
                ExpandingHistorySet tempEHset = new ExpandingHistorySet();
                
                for (int i = 0; i < ehset.size(); i++) {
                    ExpandingHistory ex = this.getExistentialResources(ehset.get(i), ehset.get(i).getInstanceSet(), propertyHistory.get(j));
                    ExpandingHistory uv = this.getUniversalResources(ehset.get(i), ehset.get(i).getInstanceSet(), propertyHistory.get(j));                      
                    
                    tempEHset.add(ex);
                    tempEHset.add(uv);
                }
                
                ehset.removeAllElements();
                ehset.addAll(tempEHset);
            }
        }
        
        return ehset;
    }
    
//    private 
    
    private ExpandingHistory getExistentialResources(ExpandingHistory eh, List<Resource> instanceSet, PropertyArc pa){
                
        Vector<Resource> notset = new Vector();
        Property prop = pa.getProperty();
        ExpandingHistory existSet = new ExpandingHistory();
        
        existSet.updateExpandingHistory(eh);
        existSet.add(pa, DLConstructors.EXISTENTIAL);
        
        if(pa.getDirection()){
            for (int i = 0; i < instanceSet.size(); i++) {
                boolean exist = false;
                Resource r = instanceSet.get(i);
    //            System.out.println("=   "+r.toString());
                ResIterator res = this.model.listResourcesWithProperty(prop, r);
                
                while(res.hasNext()){
                    Resource past_r = res.nextResource();
                    if(existSet.contains(past_r)){
                        continue;
                    }
                    if(notset.contains(past_r)){
                        continue;
                    }
                    NodeIterator ni = this.model.listObjectsOfProperty(past_r, prop);                
                    while(ni.hasNext()){
                        Resource r2 = ni.nextNode().asResource();
                        if(instanceSet.contains(r2)){                        
                            exist = true;
                            break;
                        }
                    }
                    if(exist){
    //                    System.out.println("past_r 추가  " + past_r);
                        existSet.addInstance(past_r);
                    }else{
                        notset.add(past_r);
                    }
                }            
            }
        }else{
            for (int i = 0; i < instanceSet.size(); i++) {
                boolean exist = false;
                Resource r = instanceSet.get(i);
                
                NodeIterator ni2 = this.model.listObjectsOfProperty(r, prop);
                while(ni2.hasNext()){
                    Resource past_r = ni2.nextNode().asResource();
                    if(existSet.contains(past_r)){                        
                        continue;
                    }
                    if(notset.contains(past_r)){                        
                        continue;
                    }
                    ResIterator res2 = this.model.listResourcesWithProperty(prop, past_r);
                    while(res2.hasNext()){
                        Resource r2 = res2.nextResource();
                        if(instanceSet.contains(r2)){
                            exist = true;
                            break;
                        }
                    }
                    if(exist){
    //                    System.out.println("past_r 추가  " + past_r);
                        existSet.addInstance(past_r);
                    }else{
                        notset.add(past_r);
                    }
                }                
            }
        }        
        
        return existSet;
    }
    
    private ExpandingHistory getUniversalResources(ExpandingHistory eh, List<Resource> instanceSet, PropertyArc pa){
        Vector<Resource> notset = new Vector();
        Property prop = pa.getProperty();
        ExpandingHistory univSet = new ExpandingHistory();
        univSet.updateExpandingHistory(eh);
        univSet.add(pa, DLConstructors.UNIVERSAL);
        
        if(pa.getDirection()){
            for (int i = 0; i < instanceSet.size(); i++) {
                boolean universal = true;
                Resource r = instanceSet.get(i);
                ResIterator res = this.model.listResourcesWithProperty(prop, r);
                while(res.hasNext()){
                    Resource past_r = res.nextResource();
                    if(univSet.contains(past_r)){
                        continue;
                    }
                    if(notset.contains(past_r)){
                        continue;
                    }
                    NodeIterator ni = this.model.listObjectsOfProperty(past_r, prop);
                    while(ni.hasNext()){
                        Resource r2 = ni.nextNode().asResource();
                        if(!instanceSet.contains(r2)){
                            universal = false;
                            notset.add(past_r);
                            break;
                        }
                    }
                    if(universal){
                        univSet.addInstance(past_r);
                    }
                }
            }
        }else{
            for (int i = 0; i < instanceSet.size(); i++) {
                boolean universal = true;
                Resource r = instanceSet.get(i);
                NodeIterator ni = this.model.listObjectsOfProperty(r, prop);
                while(ni.hasNext()){
                    Resource past_r = ni.nextNode().asResource();
                    if(univSet.contains(past_r)){
                        continue;
                    }
                    if(notset.contains(past_r)){
                        continue;
                    }                    
                    ResIterator res = this.model.listResourcesWithProperty(prop, past_r);
                    while(res.hasNext()){
                        Resource r2 = res.nextResource();
                        if(!instanceSet.contains(r2)){
                            universal = false;
                            notset.add(past_r);
                            break;
                        }
                    }
                    if(universal){
                        univSet.addInstance(past_r);
                    }
                }
            }
        }        
        return univSet;
    }
    
    private DecomposeCandidate refinementMaker(Vector<Property> propertyHistory, Vector<Resource> css){
        
        Vector<Refinement> qrset = new Vector<Refinement>();
        DecomposeCandidate dc = new DecomposeCandidate(qrset, ref_type);
        
        return dc;
    }
    
    
//    private Refinement setRefinementByType(int type){
//        Refinement r;
//        
//        if(type == RefinementType.CARDINALITYRESTRICTION){
////            r= new CardinalityRestrictionRefinement();
//        }else if(type ==RefinementType.CONCEPTCONSTRUCTOR){
//            
//        }else if(type ==RefinementType.CONJUNTION){
//            
//        }else if(type ==RefinementType.DISJUNCTION){
//            
//        }else if(type ==RefinementType.DOMAINRESTRICTION){
//            
//        }else if(type ==RefinementType.QUALIFICATION){
//            
//        }
//        
//        return r;
//    }

    
        
        
    
}
